package cn.demoncat.util.excel;

import cn.demoncat.util.lang.DoubleUtil;
import cn.demoncat.util.lang.constant.StringConstant;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

/**
 * Excel单元格工具
 *
 * @author 延晓磊
 * @since 2023年08月24日
 */
public class ExcelCellUtil {

    /**
     * 合并单元格
     *
     * 1、合并单元格后，会使用首个（左上角第一个）单元格的数据
     * 2、合并单元格，会应用首个单元格的样式，但边框不生效，所以需要分别设置（不存在的单元格要创建后设置）
     *      例：row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).setCellStyle(row.getCell(0).getCellStyle());
     *      例：sheet.getMergedRegion(0).forEach(o -> sheet.getRow(o.getRow()).getCell(o.getColumn(), Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).setCellStyle(row.getCell(0).getCellStyle()));
     * 3、删除合并单元格：实际是删除数组元素，删除后数组重新排序（删除0和1，应当调用两次删除0）
     *      例：sheet.removeMergedRegion(0)
     *      例：sheet.removeMergedRegions(CollectionUtil.toList(0, 1));
     *
     * @param sheet
     * @param firstRow
     * @param lastRow
     * @param firstCol
     * @param lastCol
     *
     * @author 延晓磊
     * @since 2023年08月24日
     */
    public static void merge(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol){
        // 合并：首行索引、尾行索引、首列索引、尾列索引
        sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
    }

    /**
     * 读取单元格
     *
     * 统一读取数据为字符串，调用者可以先判断字符串是否为空，然后再进行类型转换
     *
     * @param cell
     *
     * @author 延晓磊
     *
     * @since 2018年7月20日
     */
    public static String read(Cell cell) {
        if (cell == null) {
            return StringConstant.EMPTY;
        } else {
            // 获取cell的值(POI需对应类型读取)
            switch (cell.getCellType()) {
                case STRING:
                    //  文本
                    return cell.getStringCellValue();
                case BLANK:
                case ERROR:
                    // 为空、错误
                    return StringConstant.EMPTY;
                case FORMULA:
                    // 公式
                    try {
                        // 数值
                        return DoubleUtil.toString(cell.getNumericCellValue());
                    }catch (Exception e){
                        try {
                            // 文本
                            return cell.getStringCellValue();
                        }catch (Exception e1){
                            // 错误
                            return StringConstant.EMPTY;
                        }
                    }
                default:
                    // 数字、日期
                    return new DataFormatter().formatCellValue(cell);
            }
        }
    }
}
